package socket.demo1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

public class Client extends Thread {
    private String address = "127.0.0.1"; //ip地址
    private int port = 9876;//端口号

    public Client() {
        Socket client;//创建客户端
        System.out.println("客户端已启动！");

        for (int i = 0; i < 10; i++) {//使用for循环，一共发送10组状态。
            client = new Socket();
            Msg data = new Msg(i % 2);//创建Msg对象，i%2代表状态变量，data为要发送的数据。

            //InetSocketAddres是SocketAddress的子类，使用这个类来向connect方法传递服务器的IP地址和端口号。
            InetSocketAddress isa = new InetSocketAddress(this.address, this.port);
            try {
                client.connect(isa, 10000);//使用isa连接服务器，并设置一个超时时间10000毫秒，模拟超时定时器。
                ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
                out.writeObject(data);//使用对象输出流发送之前模拟好的状态、数据data。
                System.out.println("发送分组 " + data.getStateValue());
                BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));//接收服务端返回的数据。
                String str = br.readLine();//读取服务端返回的数据，根据不同的信息选择接下来的操作。
                if (str.equals("resend1")) {//当返回的数据为"resend1"时，表示数据丢失状态，客户端重新发送该分组。并把i减1，不改变状态变量。
                    System.out.println("数据丢失，重发" + "\n");
                    i--;
                    //将相关对象置为空
                    client.close();

                    continue;
                } else if (str.equals("resend2")) {//当返回的数据为"resend2"时，表示ACK丢失状态，客户端重新发送该分组。并把i减1，不改变状态变量。
                    System.out.println("ACK丢失，重发" + "\n");
                    i--;
                    //将相关对象置为空
                    client.close();

                    continue;
                } else if (str.equals("NCK")) {//当返回的数据为"NCK"时，表示数据错误状态。i减1，不改变状态变量。
                    System.out.println("数据错误" + "\n");
                    i--;
                    //将相关对象置为空
                    client.close();

                    continue;
                } else {////当返回的数据为"ACK"时，没有错误。
                    System.out.println("接收ACK" + data.getStateValue() + "\n");
                    //将相关对象置为空
                    client.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //之下的代码与上述代码类似，此过程为在发送完10个分组以后，发送结束信号，并接受服务端的结束信号，关闭客户端。
        Socket client0 = new Socket();
        InetSocketAddress isa = new InetSocketAddress(this.address, this.port);
        try {
            client0.connect(isa, 10000);
            ObjectOutputStream out = new ObjectOutputStream(client0.getOutputStream());
            Msg data0 = new Msg(2);//此时的data0是结束信号
            out.writeObject(data0);
            BufferedReader br = new BufferedReader(new InputStreamReader(client0.getInputStream()));
            String str = br.readLine();
            if (str.equals("over too!")) {
                System.out.println("结束！客户端关闭！");
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new Client();
    }
}
